package com.wmyg.antifake.gs1;

import com.wmyg.antifake.gs1.ns2.converters.ResponseConverter;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

/**
 * @program: antifake
 * @description: 物码中心接口工具
 * @author: wong
 * @create: 19-4-23
 */
public class GS1Utils {

    private static final String GLN_PRE = "/AAQI/v1/ProductData/gtin/0";

    private static final String GLN_SUB= "?targetMarket=156&dataVersion=1.1&clientGln=6901234501421";

    private static final String KEY = "kwdTZyGu2qjElblN8OR0wyq2K+24dObKC8DgScNQ/GM=";

    private static final String WEBSITE = "http://api.chinatrace.org";

    public static GS1Result getGS1Info(String gtin) {
        GS1Result result = null;
        String resultDomXml = getResponseFromGS1China(gtin);
        if (resultDomXml.isEmpty()) {
            result = new GS1Result(1, null);
        } else {
            try {
                Document doc = DocumentHelper.parseText(resultDomXml);
                result = new GS1Result(0, ResponseConverter.converter(doc.getRootElement()));
                if (null != result.getResponse().getExceptionMessage()) {
                    result.setCode(1);
                }
            } catch (Exception e) {
                e.printStackTrace();
                result = new GS1Result(1, null);
            }
        }
        return result;
    }

    public static String getResponseFromGS1China(String gtin) {
        String resultXml = "";
        Mac mac = null;
        byte[] secretByte;
        SecretKey secretKey;
        String resultMac = "";
        byte[] digest;
        String gln = GLN_PRE + gtin + GLN_SUB;
        BufferedReader buffer = null;
        StringBuffer resultBuffer = null;
        try {
            mac = Mac.getInstance("HmacSHA256");
            secretByte = DatatypeConverter.parseBase64Binary(KEY);
            byte[] dataByte = gln.getBytes(StandardCharsets.US_ASCII);
            secretKey = new SecretKeySpec(secretByte, "HMACSHA256");
            mac.init(secretKey);
            digest = mac.doFinal(dataByte);
            resultMac = toHex(digest);
            resultMac = resultMac.toUpperCase();
            URL url = new URL(WEBSITE + gln + "&mac=" + resultMac);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            con.setRequestMethod("GET");
            con.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);

            InputStream inputStream = null;
            if (con.getResponseCode() == HttpURLConnection.HTTP_OK) {
                inputStream = con.getInputStream();
            } else {
                inputStream = con.getErrorStream();
            }
            resultBuffer = new StringBuffer();
            String line;
            buffer = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            while ((line = buffer.readLine()) != null) {
                resultBuffer.append(line);
            }
            resultXml = resultBuffer.toString();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultXml;
    }

    private static String toHex(byte[] src){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

}
